package org.eclipse.epsilon.emc.spreadsheets.csv.read;

import static org.junit.Assert.assertTrue;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.eclipse.epsilon.common.util.FileUtil;
import org.eclipse.epsilon.emc.spreadsheets.SpreadsheetRow;
import org.eclipse.epsilon.emc.spreadsheets.csv.CsvModel;
import org.eclipse.epsilon.emc.spreadsheets.csv.CsvRow;
import org.eclipse.epsilon.emc.spreadsheets.csv.CsvWorksheet;
import org.eclipse.epsilon.eol.EolModule;
import org.eclipse.epsilon.eol.exceptions.models.EolModelElementTypeNotFoundException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class NoHeaderReadTest
{
	private static CsvModel model = null;
	private static String filePath = "resources/CsvFile.txt";

	@BeforeClass
	public static void setUpFileAndLoad() throws Exception
	{
		FileUtil.setFileContents("", new File(filePath));
		setUp();
		for (int i = 0; i < 1000; i++)
		{
			Map<String, Object> values = new HashMap<String, Object>();
			values.put("c_0", i);
			values.put("c_1", "value1");
			values.put("c_2", "value2");
			values.put("c_3", "value3");
			values.put("c_4", "value4");
			values.put("c_5", "value5");
			model.createInstance(CsvWorksheet.NAME, values);
		}
	}

	private static void setUp() throws Exception
	{
		model = new CsvModel();
		model.setFile(filePath);
		model.setConfigurationFile("resources/CsvFileTestConfig.xml");
		model.setHasHeader(false);
		model.setStoredOnDisposal(false);
		model.setName("MODEL");
		model.load();
	}

	@Test
	public void readAllRows() throws EolModelElementTypeNotFoundException
	{
		CsvWorksheet worksheet = (CsvWorksheet) model.getWorksheetByType(CsvWorksheet.NAME);
		List<SpreadsheetRow> rows = (List<SpreadsheetRow>) model.getAllOfKind(CsvWorksheet.NAME);
		assertTrue(CollectionUtils.isNotEmpty(rows));
		assertTrue(rows.size() == 1000);
		for (int i = 0; i < rows.size(); i++)
		{
			CsvRow row = (CsvRow) rows.get(i);
			assertTrue(row.getVisibleCellValue(worksheet.getColumn("col0")).equals(String.valueOf(i)));
			assertTrue(row.getVisibleCellValue(worksheet.getColumn("col1")).equals("value1"));
			assertTrue(row.getVisibleCellValue(worksheet.getColumn("col2")).equals("value2"));
			assertTrue(row.getVisibleCellValue(worksheet.getColumn("col3")).equals("value3"));
			assertTrue(row.getVisibleCellValue(worksheet.getColumn("col4")).equals("value4"));
			assertTrue(row.getVisibleCellValue(worksheet.getColumn("col5")).equals("value5"));
		}
	}

	@SuppressWarnings("unchecked")
	@Test
	public void readAllRowsWithEOL() throws Exception
	{
		final EolModule module = new EolModule();
		module.parse("return MODEL!CSV.all;");
		module.getContext().getModelRepository().addModel(model);
		Object result = module.execute();

		List<SpreadsheetRow> rows = new ArrayList<SpreadsheetRow>((Collection<SpreadsheetRow>) result);
		for (int i = 0; i < rows.size(); i++)
		{
			CsvRow row = (CsvRow) rows.get(i);
			assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col0")).equals(String.valueOf(i)));
			assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col1")).equals("value1"));
			assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col2")).equals("value2"));
			assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col3")).equals("value3"));
			assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col4")).equals("value4"));
			assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col5")).equals("value5"));
		}
	}

	@SuppressWarnings("unchecked")
	@Test
	public void readAllRowsColumnWithEOL() throws Exception
	{
		final EolModule module = new EolModule();
		module.parse("return MODEL!CSV.all.col0;");
		module.getContext().getModelRepository().addModel(model);
		Object result = module.execute();

		List<String> values = new ArrayList<String>((Collection<String>) result);
		for (int i = 0; i < values.size(); i++)
		{
			assertTrue(values.get(i).equals(String.valueOf(i)));
		}
	}

	@Test
	public void readFirstWithEOL() throws Exception
	{
		final EolModule module = new EolModule();
		module.parse("return MODEL!CSV.all.first();");
		module.getContext().getModelRepository().addModel(model);
		Object result = module.execute();

		CsvRow row = (CsvRow) result;
		assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col0")).equals(String.valueOf(0)));
		assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col1")).equals("value1"));
		assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col2")).equals("value2"));
		assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col3")).equals("value3"));
		assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col4")).equals("value4"));
		assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col5")).equals("value5"));
	}

	@Test
	public void readLastWithEOL() throws Exception
	{
		final EolModule module = new EolModule();
		module.parse("return MODEL!CSV.all.last();");
		module.getContext().getModelRepository().addModel(model);
		Object result = module.execute();

		CsvRow row = (CsvRow) result;
		assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col0")).equals(String.valueOf(999)));
		assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col1")).equals("value1"));
		assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col2")).equals("value2"));
		assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col3")).equals("value3"));
		assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col4")).equals("value4"));
		assertTrue(row.getVisibleCellValue(row.getWorksheet().getColumn("col5")).equals("value5"));
	}

	@AfterClass
	public static void tearDown() throws Exception
	{
		FileUtil.setFileContents("", new File(filePath));
	}

}
